//! `std::fs` 模块的测试用例
//!
//! 本文件包含对 `std::fs` 中文件系统操作的测试。
//! 注意：这些测试会与文件系统进行交互，可能会创建、修改或删除文件和目录。
//! 测试将在一个临时的 `test_temp_dir` 目录中进行，以避免污染项目目录。

#[cfg(test)]
mod tests {
    use std::fs::{self, File, OpenOptions};
    use std::io::{Read, Write};
    use std::path::Path;

    /// 测试辅助函数：创建临时目录，并在测试结束后清理
    fn setup_test_dir() -> &'static str {
        let test_dir = "test_temp_dir";
        // 清理之前的测试目录（如果存在）
        if Path::new(test_dir).exists() {
            fs::remove_dir_all(test_dir).expect("Failed to remove old test directory");
        }
        // 创建新的测试目录
        fs::create_dir(test_dir).expect("Failed to create test directory");
        test_dir
    }

    /// 测试辅助函数：清理临时目录
    fn cleanup_test_dir(test_dir: &str) {
        fs::remove_dir_all(test_dir).expect("Failed to clean up test directory");
    }

    /// 测试文件的创建、写入和���取
    #[test]
    fn test_file_create_write_read() {
        let test_dir = setup_test_dir();
        let file_path = Path::new(test_dir).join("test_file.txt");

        // 创建并写入文件
        {
            let mut file = File::create(&file_path).expect("Failed to create file");
            file.write_all(b"Hello, Rust FS!")
                .expect("Failed to write to file");
        }

        // 读取文件内容
        {
            let mut file = File::open(&file_path).expect("Failed to open file");
            let mut contents = String::new();
            file.read_to_string(&mut contents)
                .expect("Failed to read file");
            assert_eq!(contents, "Hello, Rust FS!");
        }

        cleanup_test_dir(test_dir);
    }

    /// 测试目录的创建和删除
    #[test]
    fn test_directory_create_remove() {
        let test_dir = setup_test_dir();
        let new_dir_path = Path::new(test_dir).join("new_dir");

        // 创建目录
        fs::create_dir(&new_dir_path).expect("Failed to create directory");
        assert!(new_dir_path.exists() && new_dir_path.is_dir());

        // 删除目录
        fs::remove_dir(&new_dir_path).expect("Failed to remove directory");
        assert!(!new_dir_path.exists());

        cleanup_test_dir(test_dir);
    }

    /// 测试 `create_dir_all` (递归创建目录)
    #[test]
    fn test_create_dir_all() {
        let test_dir = setup_test_dir();
        let nested_dir_path = Path::new(test_dir).join("a/b/c");

        // 递归创建目录
        fs::create_dir_all(&nested_dir_path).expect("Failed to create nested directories");
        assert!(nested_dir_path.exists() && nested_dir_path.is_dir());

        cleanup_test_dir(test_dir);
    }

    /// 测试 `read_dir` (读取目录内容)
    #[test]
    fn test_read_dir() {
        let test_dir = setup_test_dir();
        File::create(Path::new(test_dir).join("file1.txt")).unwrap();
        File::create(Path::new(test_dir).join("file2.txt")).unwrap();
        fs::create_dir(Path::new(test_dir).join("subdir")).unwrap();

        let entries: Vec<_> = fs::read_dir(test_dir)
            .expect("Failed to read directory")
            .map(|res| res.unwrap().file_name().into_string().unwrap())
            .collect();

        assert_eq!(entries.len(), 3);
        assert!(entries.contains(&"file1.txt".to_string()));
        assert!(entries.contains(&"file2.txt".to_string()));
        assert!(entries.contains(&"subdir".to_string()));

        cleanup_test_dir(test_dir);
    }

    /// 测试文件的重命名和复制
    #[test]
    fn test_file_rename_copy() {
        let test_dir = setup_test_dir();
        let original_path = Path::new(test_dir).join("original.txt");
        let renamed_path = Path::new(test_dir).join("renamed.txt");
        let copied_path = Path::new(test_dir).join("copied.txt");

        File::create(&original_path).unwrap();

        // 复制文件
        fs::copy(&original_path, &copied_path).expect("Failed to copy file");
        assert!(copied_path.exists());

        // 重命名文件
        fs::rename(&original_path, &renamed_path).expect("Failed to rename file");
        assert!(!original_path.exists());
        assert!(renamed_path.exists());

        cleanup_test_dir(test_dir);
    }

    /// 测试 `OpenOptions`
    #[test]
    fn test_open_options() {
        let test_dir = setup_test_dir();
        let file_path = Path::new(test_dir).join("append_test.txt");

        // 第一次写入
        let mut file = OpenOptions::new()
            .create(true)
            .write(true)
            .truncate(true)
            .open(&file_path)
            .unwrap();
        file.write_all(b"First line.\n").unwrap();

        // 第二次追加写入
        let mut file = OpenOptions::new().append(true).open(&file_path).unwrap();
        file.write_all(b"Second line.\n").unwrap();

        // 验证内容
        let contents = fs::read_to_string(&file_path).unwrap();
        assert_eq!(contents, "First line.\nSecond line.\n");

        cleanup_test_dir(test_dir);
    }

    /// 测试 `metadata` (获取文件元数据)
    #[test]
    fn test_metadata() {
        let test_dir = setup_test_dir();
        let file_path = Path::new(test_dir).join("metadata_test.txt");
        File::create(&file_path).unwrap();

        let metadata = fs::metadata(&file_path).expect("Failed to get metadata");

        assert!(metadata.is_file());
        assert!(!metadata.is_dir());
        assert_eq!(metadata.len(), 0); // 文件为空
    }
}
